package com.gitee.wsl.ext.array



fun ByteArray.byteType(): Int {
    val raw = this
    var utf8 = 0
    var ascii = 0
    if (raw.size > 3) {
        if (raw[0].toInt() == 0xEF && raw[1].toInt() == 0xBB && raw[2].toInt() == 0xBF) {
            return 100
        }
    }
    val len: Int = raw.size
    var child = 0
    var i: Int = 0
    while (i < len) {

        // UTF-8 byte shouldn't be FF and FE
        if (raw[i].toInt() and 0xFF.toByte().toInt() == 0xFF.toByte()
                .toInt() || raw[i].toInt() and 0xFE.toByte().toInt() == 0xFE.toByte().toInt()
        ) {
            return 0
        }
        if (child == 0) {
            // ASCII format is 0x0*******
            if (raw[i].toInt() and 0x7F.toByte()
                    .toInt() == raw[i].toInt() && raw[i].toInt() != 0
            ) {
                ascii++
            } else if (raw[i].toInt() and 0xC0.toByte().toInt() == 0xC0.toByte().toInt()) {
                // 0x11****** maybe is UTF-8
                for (bit in 0..7) {
                    child = if ((0x80 shr bit).toByte()
                            .toInt() and raw[i].toInt() == (0x80 shr bit).toByte()
                            .toInt()
                    ) {
                        bit
                    } else {
                        break
                    }
                }
                utf8++
            }
            i++
        } else {
            child = if (raw.size - i > child) child else raw.size - i
            var currentNotUtf8 = false
            for (children in 0 until child) {
                // format must is 0x10******
                if (raw[i + children].toInt() and 0x80.toByte().toInt() != 0x80.toByte()
                        .toInt()
                ) {
                    if (raw[i + children].toInt() and 0x7F.toByte()
                            .toInt() == raw[i + children].toInt() && raw[i].toInt() != 0
                    ) {
                        // ASCII format is 0x0*******
                        ascii++
                    }
                    currentNotUtf8 = true
                }
            }
            if (currentNotUtf8) {
                utf8--
                i++
            } else {
                utf8 += child
                i += child
            }
            child = 0
        }
    }
    // UTF-8 contains ASCII
    return if (ascii == len) {
        100
    } else (100 * ((utf8 + ascii).toFloat() / len.toFloat())).toInt()
}